package com.suning.sawp.service.impl.returngoods;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import redis.clients.jedis.Jedis;

import com.google.gson.reflect.TypeToken;
import com.suning.framework.sedis.JedisAction;
import com.suning.framework.sedis.JedisClient;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.dto.bi.StoreRetGdsRankListDto;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.returngoods.RetGdsRateChartRtn;
import com.suning.sawp.dto.returngoods.RetGdsStatisListRtn;
import com.suning.sawp.dto.returngoods.RetGdsStatisRtn;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.intf.returngoods.ReturnGoodsDaoService;
import com.suning.sawp.intf.returngoods.ReturnGoodsService;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.GsonUtils;
import com.suning.sawp.service.util.RedisCacheUtils;

/**
 * 
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 * 
 * @author Wuxiao
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class ReturnGoodsServiceImpl implements ReturnGoodsService {

    @Resource
    StoreManService             storeManService;

    @Resource
    ReturnGoodsDaoService       returnGoodsDaoService;

    @Resource
    JedisClient                 jedisClient;

    @Resource
    RedisCacheUtils             cacheUtils;

    private static final String SEPARATOR = ",";
    
    private static final String DATE_FORMAT = "yyyy-MM-dd";

    private static final Logger LOGGER    = LoggerFactory.getLogger(ReturnGoodsServiceImpl.class);

    @Override
    public ReturnMsg<List<RetGdsRateChartRtn>> queryRtnGdsChart(String staffId,
            String categoryCode, String queryType) {
        ReturnMsg<List<RetGdsRateChartRtn>> ret = new ReturnMsg<List<RetGdsRateChartRtn>>();
        if (StringUtils.isBlank(queryType)) {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E001,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
            return ret;
        }
        //查询工号对应的门店信息
        StoreManDto storeManInfo = storeManService.queryStoreManAttachInfo(staffId);
        if (storeManInfo == null) {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E004,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
            return ret;
        }
        //判断是否有权限
        int checkFlag = checkPermission(staffId, categoryCode, storeManInfo.getPositionId(),
                storeManInfo.getCategories());
        if (checkFlag > 0) {
            String storeCode = storeManInfo.getStoreCode();
            String field = queryType + storeCode;
            if (checkFlag == 1 && StringUtils.isNotBlank(categoryCode)) {
                field = field + categoryCode;
            }
            Type type = new TypeToken<List<RetGdsRateChartRtn>>() {
            }.getType();
            //从缓存中取数据
            List<RetGdsRateChartRtn> list = cacheUtils.hget(
                    CacheKeyConstants.STORE_RET_GDS_CHART_LIST, field, type);
            if (list != null) {
                ret.setData(list);
                return ret;
            }
            list = new ArrayList<RetGdsRateChartRtn>();
            //如果是店长，忽略品类
            if(checkFlag == 2){
                categoryCode = "";
            }
            if (RetGdsRateChartRtn.queryType.DAY.equals(queryType)) {
                list = returnGoodsDaoService.queryRetGdsStatisByDay(storeCode, categoryCode);
            } else if (RetGdsRateChartRtn.queryType.MONTH.equals(queryType)) {
                list = returnGoodsDaoService.queryRetGdsStatisByMonth(storeCode, categoryCode);
            } else if (RetGdsRateChartRtn.queryType.WEEK.equals(queryType)) {
                list = returnGoodsDaoService.queryRetGdsStatisByWeek(storeCode, categoryCode);
            }
            cacheUtils.hsetWithMyExpireTime(CacheKeyConstants.STORE_RET_GDS_CHART_LIST, field,
                    list, CacheKeyConstants.STORE_RET_GDS_CHART_EXPIRE_TIME);
            ret.setData(list);
        } else if (checkFlag == 0) {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E003,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
        } else {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E002,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
        }
        return ret;
    }

    private int checkPermission(String staffId, String categoryCode, String positionId,
            List<Category> categories) {
        //只有店长和督导有权限
        if (ClerkConstants.SALE_GUIDE.equals(positionId)) {
            if (StringUtils.isNotBlank(categoryCode) && CollectionUtils.isNotEmpty(categories)) {
                for (Category cate : categories) {
                    if (categoryCode.equals(cate.getCategoryCode())) {
                        return 1;
                    }
                }
            }
            return 0;
        } else if(ClerkConstants.STORE_KEEPER.equals(positionId)){
            return 2;
        }
        return -1;
    }

    @Override
    public ReturnMsg<RetGdsStatisRtn> queryRetGdsDetail(String staffId,
            String branchCodes, String categoryCodes, Integer limit, Integer startIndex,
            String queryType, String sortType, String sumType) {
        ReturnMsg<RetGdsStatisRtn> ret = new ReturnMsg<RetGdsStatisRtn>();
        RetGdsStatisRtn queryRet = new RetGdsStatisRtn();
        StoreManDto storeManInfo = storeManService.queryStoreManAttachInfo(staffId);
        startIndex = startIndex == null ? 0 : startIndex;
        limit = limit == null ? 10 : limit;
        if (storeManInfo == null) {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E004,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
            return ret;
        }
        List<String> branchList = new ArrayList<String>();
        if (StringUtils.isNotBlank(branchCodes)) {
            String[] branch = branchCodes.split(SEPARATOR);
            for (String branchCode : branch) {
                branchList.add(branchCode);
            }
        }
        List<String> cateCodeList = new ArrayList<String>();
        if (StringUtils.isNotBlank(categoryCodes)) {
            String[] cate = categoryCodes.split(SEPARATOR);
            for (String cateCode : cate) {
                cateCodeList.add(cateCode);
            }
        }
        if(ClerkConstants.SALE_GUIDE.equals(storeManInfo.getPositionId()) && cateCodeList.size() > 1){
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E001, ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
            return ret;
        }
        int checkFlag = checkPermission(staffId, cateCodeList.size() > 0 ? cateCodeList.get(0) : "", storeManInfo.getPositionId(),
                storeManInfo.getCategories());
        if (checkFlag > 0) {
            String storeCode = storeManInfo.getStoreCode();
            List<RetGdsStatisListRtn> list = new ArrayList<RetGdsStatisListRtn>();
            int count = 0;
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DATE, -1);
            queryRet.setStatisEndTime(DateUtils.getDateStrByFormat(c.getTime(), DATE_FORMAT));
            if (RetGdsStatisListRtn.queryType.DAY.equals(queryType)) {
                count = returnGoodsDaoService.queryCountRetGdsDetailByDay(branchList, cateCodeList,
                        sortType, sumType, storeCode);
                list = returnGoodsDaoService.queryRetGdsStatisDetailByDay(branchList, cateCodeList,
                        sortType, sumType, startIndex, limit, storeCode);
            } else if (RetGdsStatisListRtn.queryType.MONTH.equals(queryType)) {
                count = returnGoodsDaoService.queryCountRetGdsDetailByMonth(branchList,
                        cateCodeList, sortType, sumType, storeCode);
                list = returnGoodsDaoService.queryRetGdsStatisDetailByMonth(branchList,
                        cateCodeList, sortType, sumType, startIndex, limit, storeCode);
                c.add(Calendar.DATE, 1-c.get(Calendar.DAY_OF_MONTH));
            } else if (RetGdsStatisListRtn.queryType.WEEK.equals(queryType)) {
                count = returnGoodsDaoService.queryCountRetGdsDetailByWeek(branchList,
                        cateCodeList, sortType, sumType, storeCode);
                list = returnGoodsDaoService.queryRetGdsStatisDetailByWeek(branchList,
                        cateCodeList, sortType, sumType, startIndex, limit, storeCode);
                if (c.get(Calendar.DAY_OF_WEEK) == 1) {
                    c.add(Calendar.DATE,-6);
                } else {
                    c.add(Calendar.DATE, 1 - c.get(Calendar.DAY_OF_WEEK) + 1);
                }
            }
            queryRet.setStatisStartTime(DateUtils.getDateStrByFormat(c.getTime(), DATE_FORMAT));
            queryRet.setTotalSize(count);
            queryRet.setRecords(list);
            ret.setData(queryRet);
        } else if (checkFlag == 0) {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E003,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
        } else {
            ret.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E002,
                    ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
        }
        return ret;
    }

    @Override
    public ReturnMsg<List<StoreRetGdsRankListDto>> getStoreRetGdsRankList(String staffId,
            String cateCode) {
        ReturnMsg<List<StoreRetGdsRankListDto>> returnMsg = new ReturnMsg<List<StoreRetGdsRankListDto>>();
        List<StoreRetGdsRankListDto> list = null;
        // 取缓存数据
        final String key = CacheKeyConstants.STORE_RET_GDS_RANK_LIST + staffId
                + (StringUtils.isNotBlank(cateCode) ? ("_" + cateCode) : "");
        String json = jedisClient.execute(new JedisAction<String>() {
            @Override
            public String doAction(Jedis jedis) {
                return jedis.get(key);
            }
        });
        if (StringUtils.isNotBlank(json)) {
            // 缓存存在
            TypeToken<List<StoreRetGdsRankListDto>> typeToken = new TypeToken<List<StoreRetGdsRankListDto>>() {
            };
            list = GsonUtils.fromJson(json, typeToken);
        } else {
            // 缓存不存在
            StoreManDto manDto = storeManService.queryStoreManAttachInfo(staffId);
            if (null == manDto) {
                // 个人信息查询失败，则返回系统异常
                returnMsg.setError(ErrorCodeConstants.ERR_0002);
                LOGGER.error("StoreRetGdsService.getStoreRetGdsRankList ");
            } else {
                //昨天所在日期的月份
                Date yestd = DateUtils.getNextDay(new Date(), -1);
                String month = DateUtils.getDateStrByFormat(yestd, DateUtils.YYYYMM_PATTERN);
                if (ClerkConstants.STORE_KEEPER.equals(manDto.getPositionId())) {
                    // 店长
                    list = returnGoodsDaoService.queryStoreRetGdsRankList(manDto.getRegionCode(), month);
                } else if (ClerkConstants.SALE_GUIDE.equals(manDto.getPositionId())) {
                    // 督导
                    list = returnGoodsDaoService.queryStoreCateRetRankList(manDto.getRegionCode(),
                            cateCode, month);
                } else {
                    // 其他角色无权限看到
                    returnMsg.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E002);
                }
                if (CollectionUtils.isNotEmpty(list)) {
                    // 计算排行
                    int size = list.size();
                    for (int i = 0; i < size; i++) {
                        StoreRetGdsRankListDto dto = list.get(i);
                        dto.setRank(i + 1);
                        if (i > 0) {
                            StoreRetGdsRankListDto last = list.get(i - 1);
                            if (last.getRetGdsRate().equals(dto.getRetGdsRate())) {
                                dto.setRank(i);
                            }
                        }
                    }
                } else {
                    // 排行榜为空
                    list = new ArrayList<StoreRetGdsRankListDto>();
                }
                // 加入缓存
                final String retJson = GsonUtils.toJson(list, false);
                jedisClient.execute(new JedisAction<String>() {
                    @Override
                    public String doAction(Jedis jedis) {
                        return jedis.setex(key, CacheKeyConstants.STORE_RET_GDS_RANK_LIST_EXPIRE_TIME, retJson);
                    }
                });
            }
        }

        returnMsg.setData(list);
        return returnMsg;
    }
}
